package com.ahwei.shop.auth.controller;

import com.ahwei.r.R;
import com.ahwei.r.ResultCode;
import com.ahwei.shop.auth.entity.User;
import com.ahwei.shop.auth.entity.UserOauth;
import com.ahwei.shop.auth.service.UserOauthService;
import com.ahwei.shop.auth.service.UserService;
import com.ahwei.shop.auth.util.JwtTokenUtil;
import com.ahwei.shop.auth.util.ResponseUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.JOSEException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 第三方登录！
 * </p>
 *
 * @author ahWei
 * @email：ahwei163@qq.com
 * @since 2022-06-10 15:19:10
 */
@RestController
public class ThirdPartyLoginController {
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private UserService userService;
    @Autowired
    private UserOauthService userOauthService;
    @Autowired
    private ResponseUtils responseUtils;
    /**
     * 可以根据平台的不同从配置中读取
     */
    String clientId = "94ee878759c9550f79bf7e9c15293bacc3252bee711efef35e9dddd456f25cab";
    String clientSecret = "4468c0d400827e2dabdec7763e10fa47ad2569791beaf29e607763764c0190e3";
    String redirectUri = "http://localhost:57031/oauth.html";

    @PostMapping("/third-party-login")
    public void thirdPartyLogin(String code, HttpServletResponse response) throws Exception {
        // 1. 如果没有授权码
        if((code == null) || ("".equals(code))) {
            authenticationFailure(response);
            return;
        }

        try {
            // 2. 使用授权码从Gitee中获取access_token
            String accessToken = getAccessToken(code);

            // 3. 使用access_token从Gitee中获取用户信息
            Map<String, Object> giteeUser = getGiteeUser(accessToken);
            System.out.println("gitUser: " + giteeUser);
            // 4. 判断本地库中是否已有用户，没有则写用户，有则读取用户
            User user = getLocalUser(giteeUser);
            System.out.println(user);
            // 5.1. 返回登录结果
            authenticationSuccess(user, response);
        } catch (Exception e) {
            // 5.2. 登录失败
            authenticationFailure(response);
        }
    }

    private String getAccessToken(String code) {
        // 构建获取access_token的URL
        String url = "https://gitee.com/oauth/token?grant_type=authorization_code"
                + "&code=" + code
                + "&client_id=" + clientId
                + "&client_secret=" + clientSecret
                + "&redirect_uri=" + redirectUri;

        // 用RestTemplate访问Gitee
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, null, String.class);
        // {"access_token":"2a0201c518f1a177ba6033eef3ac3a8b","token_type":"bearer","expires_in":86400,"refresh_token":"b17ff0fb8d1a46bb7d1ea0a4961089108bf60c58e0913b3af1c2dc68795e8bfb","scope":"user_info","created_at":1628346458}
        // System.out.println("responseEntity.getBody():" + responseEntity.getBody());

        String split = responseEntity.getBody().split(":")[1];
        String accessToken = split.split("\"")[1];
        return accessToken;
    }

    private Map<String, Object> getGiteeUser(String access_token) throws JsonProcessingException {
        // https://gitee.com/api/v5/user?access_token={your_token}
        String url = "https://gitee.com/api/v5/user?access_token=" + access_token;

        // 用RestTemplate访问Gitee
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        System.out.println("responseEntity.getBody():" + responseEntity.getBody());

        // {"id":7504504,"login":"filteraid","name":"filteraid","avatar_url":"https://gitee.com/assets/no_portrait.png","url":"https://gitee.com/api/v5/users/filteraid","html_url":"https://gitee.com/filteraid","followers_url":"https://gitee.com/api/v5/users/filteraid/followers","following_url":"https://gitee.com/api/v5/users/filteraid/following_url{/other_user}","gists_url":"https://gitee.com/api/v5/users/filteraid/gists{/gist_id}","starred_url":"https://gitee.com/api/v5/users/filteraid/starred{/owner}{/repo}","subscriptions_url":"https://gitee.com/api/v5/users/filteraid/subscriptions","organizations_url":"https://gitee.com/api/v5/users/filteraid/orgs","repos_url":"https://gitee.com/api/v5/users/filteraid/repos","events_url":"https://gitee.com/api/v5/users/filteraid/events{/privacy}","received_events_url":"https://gitee.com/api/v5/users/filteraid/received_events","type":"User","blog":null,"weibo":null,"bio":null,"public_repos":9,"public_gists":0,"followers":0,"following":0,"stared":0,"watched":19,"created_at":"2020-04-27T20:49:50+08:00","updated_at":"2021-05-18T15:09:51+08:00","email":null}
        // 将json字符串转成map结合解析出来，并打印(这里以解析成map为例)
        return objectMapper.readValue(responseEntity.getBody(), Map.class);
    }

    private User getLocalUser(Map<String, Object> giteeUser) {
        // 1. 判断本地库是否有用户
        QueryWrapper<UserOauth> userOauthQueryWrapper = new QueryWrapper<>();
        userOauthQueryWrapper.eq("oauth_user_id", giteeUser.get("id"));
        UserOauth userOauth = userOauthService.getOne(userOauthQueryWrapper);

        // 2. 如果有则读取
        if(userOauth != null) {
            return userService.getById(userOauth.getUserId());
        }

        // 3. 如果没有则写入
        // 写入acl_user
        User user = new User();
        user.setUsername((String)giteeUser.get("login"));
        user.setNickName((String)giteeUser.get("name"));
        userService.save(user);

        // 写入acl_user_oauth
        UserOauth oauth = new UserOauth();
        oauth.setSource("Gitee");
        oauth.setOauthUserId(((Integer)giteeUser.get("id")).toString());
        oauth.setUserId(user.getId());
        userOauthService.save(oauth);

        // 返回user
        return user;
    }

    /**
     * 认证成功操作
     * @param user .
     * @param response .
     */
    public void authenticationSuccess(User user, HttpServletResponse response) throws IOException, JOSEException {
        String token = JwtTokenUtil.generateTokenByRSA(user.getUsername());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("user", user);

        responseUtils.outWriter(R.ok(map),HttpStatus.OK.value(),response);
    }

    /**
     * 身份认证失败
     * @param response .
     */
    public void authenticationFailure(HttpServletResponse response) throws IOException {
        // 认证失败后返回响应码401
        responseUtils.outWriter(R.error(ResultCode.LOGIN_ERROR,"登录失败",null),HttpStatus.UNAUTHORIZED.value(),response);
    }
}
